package com.whoiszxl.core.base;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.whoiszxl.core.annotation.Query;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Slf4j
public class BaseSupport {

    public static <Q, M> void buildQuery(Q query, Field field, QueryWrapper<M> queryWrapper) {
        boolean accessible = field.isAccessible();
        try {
            field.setAccessible(true);
            Query queryAnno = field.getAnnotation(Query.class);
            if(queryAnno == null) {
                return;
            }

            Object fieldValue = field.get(query);
            if(ObjectUtil.isEmpty(fieldValue)) {
                return;
            }

            parse(queryAnno, field.getName(), fieldValue, queryWrapper);
        }catch (Exception e) {
            log.error("BaseController|构建查询条件出错|{}", query, e);
        }finally {
            field.setAccessible(accessible);
        }
    }

    /**
     * 获取class和class父类的所有属性
     * @param clazz 类型
     * @param fieldList 属性列表
     * @return 查询条件里的所有字段
     * @param <Q> 查询条件类型
     */
    public static <Q> List<Field> getClassField(Class<Q> clazz, List<Field> fieldList) {
        if(clazz != null) {
            fieldList.addAll(Arrays.asList(clazz.getDeclaredFields()));
            getClassField(clazz.getSuperclass(), fieldList);
        }
        return fieldList;
    }

    public static <M> void parse(Query queryAnnotation,
                                  String fieldName,
                                  Object fieldValue,
                                  QueryWrapper<M> queryWrapper) {
        // 解析多属性模糊查询
        String blurry = queryAnnotation.blurry();
        if (StrUtil.isNotBlank(blurry)) {
            String[] propertyArr = blurry.split(",");
            queryWrapper.and(wrapper -> {
                for (String property : propertyArr) {
                    wrapper.or().like(StrUtil.toUnderlineCase(property), fieldValue);
                }
            });
            return;
        }

        // 解析单个属性查询
        String property = queryAnnotation.property();
        fieldName = StrUtil.blankToDefault(property, fieldName);
        String columnName = StrUtil.toUnderlineCase(fieldName);
        switch (queryAnnotation.type()) {
            case EQUAL:
                queryWrapper.eq(columnName, fieldValue);
                break;
            case NOT_EQUAL:
                queryWrapper.ne(columnName, fieldValue);
                break;
            case GREATER_THAN:
                queryWrapper.gt(columnName, fieldValue);
                break;
            case LESS_THAN:
                queryWrapper.lt(columnName, fieldValue);
                break;
            case GREATER_THAN_OR_EQUAL:
                queryWrapper.ge(columnName, fieldValue);
                break;
            case LESS_THAN_OR_EQUAL:
                queryWrapper.le(columnName, fieldValue);
                break;
            case BETWEEN:
                List<Object> between = new ArrayList<>((List<Object>)fieldValue);
                queryWrapper.between(columnName, between.get(0), between.get(1));
                break;
            case LEFT_LIKE:
                queryWrapper.likeLeft(columnName, fieldValue);
                break;
            case INNER_LIKE:
                queryWrapper.like(columnName, fieldValue);
                break;
            case RIGHT_LIKE:
                queryWrapper.likeRight(columnName, fieldValue);
                break;
            case IN:
                if (CollUtil.isNotEmpty((List<Object>)fieldValue)) {
                    queryWrapper.in(columnName, (List<Object>)fieldValue);
                }
                break;
            case NOT_IN:
                if (CollUtil.isNotEmpty((List<Object>)fieldValue)) {
                    queryWrapper.notIn(columnName, (List<Object>)fieldValue);
                }
                break;
            case IS_NULL:
                queryWrapper.isNull(columnName);
                break;
            case NOT_NULL:
                queryWrapper.isNotNull(columnName);
                break;
            default:
                break;
        }
    }
}
